package com.zenithmind.article.service.impl;

import com.zenithmind.article.service.ArticleFileService;
import com.zenithmind.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * 文章文件服务实现
 * 遵循单一职责原则：专注于文件操作
 * 遵循依赖倒置原则：依赖抽象接口
 */
@Slf4j
@Service
public class ArticleFileServiceImpl implements ArticleFileService {

    @Value("${article.upload.path:${user.home}/zenithmind/upload/articles}")
    private String uploadPath;
    
    @Value("${article.upload.url-prefix:http://localhost:8083/articles}")
    private String urlPrefix;
    
    private static final long MAX_COVER_SIZE = 5 * 1024 * 1024; // 5MB
    private static final List<String> ALLOWED_COVER_TYPES = Arrays.asList(
        "image/jpeg", "image/png", "image/gif", "image/webp"
    );

    @Override
    public String uploadCover(MultipartFile file) {
        log.info("开始上传文章封面，文件名：{}", file.getOriginalFilename());
        
        // 验证文件
        if (!validateFile(file)) {
            throw new BusinessException("文件验证失败");
        }

        try {
            String fileName = generateFileName(file);
            String filePath = ensureUploadDirectory();
            File dest = new File(filePath + fileName);
            
            file.transferTo(dest);
            
            String fileUrl = urlPrefix + "/" + fileName;
            log.info("文章封面上传成功，URL：{}", fileUrl);
            return fileUrl;
            
        } catch (IOException e) {
            log.error("文件上传失败", e);
            throw new BusinessException("文件上传失败：" + e.getMessage());
        }
    }

    @Override
    public Boolean deleteCover(String coverUrl) {
        if (coverUrl == null || coverUrl.isEmpty()) {
            return true;
        }
        
        try {
            // 从URL中提取文件名
            String fileName = extractFileNameFromUrl(coverUrl);
            if (fileName != null) {
                File file = new File(uploadPath + File.separator + fileName);
                if (file.exists()) {
                    boolean deleted = file.delete();
                    log.info("删除封面文件：{}，结果：{}", fileName, deleted);
                    return deleted;
                }
            }
            return true;
        } catch (Exception e) {
            log.error("删除封面文件失败：{}", coverUrl, e);
            return false;
        }
    }

    @Override
    public Boolean validateFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new BusinessException("上传文件不能为空");
        }

        // 验证文件大小
        if (file.getSize() > MAX_COVER_SIZE) {
            throw new BusinessException("文件大小不能超过 " + (MAX_COVER_SIZE / 1024 / 1024) + "MB");
        }

        // 验证文件类型
        String contentType = file.getContentType();
        if (contentType == null || !ALLOWED_COVER_TYPES.contains(contentType.toLowerCase())) {
            throw new BusinessException("不支持的文件类型，请上传 JPG, PNG, GIF 或 WebP 图片");
        }

        return true;
    }

    @Override
    public Long getMaxFileSize() {
        return MAX_COVER_SIZE;
    }

    /**
     * 生成唯一文件名
     */
    private String generateFileName(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null) {
            throw new BusinessException("文件名不能为空");
        }
        
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        return UUID.randomUUID() + suffix;
    }

    /**
     * 确保上传目录存在
     */
    private String ensureUploadDirectory() {
        String filePath = uploadPath + File.separator;
        File directory = new File(filePath);
        if (!directory.exists()) {
            boolean created = directory.mkdirs();
            if (!created) {
                throw new BusinessException("创建上传目录失败");
            }
        }
        return filePath;
    }

    /**
     * 从URL中提取文件名
     */
    private String extractFileNameFromUrl(String url) {
        if (url == null || !url.startsWith(urlPrefix)) {
            return null;
        }
        return url.substring(url.lastIndexOf("/") + 1);
    }
}
